package by.bsu.scs.presentation.action;

import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import by.bsu.scs.db.dao.UserHome;
import by.bsu.scs.model.User;
import by.bsu.scs.presentation.form.LoginForm;
import by.bsu.scs.security.MD5Encoder;
import by.bsu.scs.util.filter.AuthorizationFilter;
import by.bsu.scs.util.manager.CookiesManager;
import by.bsu.scs.util.manager.SessionManager;

/**
 * @author Alexey Hursevich
 * @version 1.0
 * 
 * All actions connected with authorization.
 */
public class LoginAction extends DispatchAction {
	
	private static final String STUDENT_SUCCESS = "student";
	private static final String INSTRUCTOR_SUCCESS = "instructor";
	private static final String ADMIN_SUCCESS = "admin";
	private static final String FAILURE = "failure";
	
	private static final String FIRST_NAME = "first_name";
	private static final String LAST_NAME = "last_name";
	
	private String userName;
	private String password;
	private boolean rememberMe = false;
	
	
	/**
	 * Responsible for authorization of system users.
	 * <p>
	 * Method checks user's cookies for user's login and password,
	 * if this data was found, tries to find user in DB
	 * by login and password. In success case it defines user's
	 * role and sets the corresponding forward path.
	 * <p>
	 * If cookies don't contain appropriate data, user's login
	 * and password are initialized from form filled by user.
	 * 
	 * @param mapping
	 * @param form from which the action was called
	 * @param request HTTP request object
	 * @param response HTTP response object
	 * 
	 * @return mapping forward path
	 */
	@SuppressWarnings("unchecked")
	public ActionForward login(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		
		LoginForm loginForm = (LoginForm) form;
		
		/*
		 * Getting user info from request parameters (if set in filter from cookies) or from submitted from
		 */
		if( ((String)request.getAttribute(AuthorizationFilter.IS_AUTORIZED)) != null &&  
		    ((String)request.getAttribute(AuthorizationFilter.IS_AUTORIZED)).equalsIgnoreCase("true")) 
		{
			userName = (String)request.getAttribute(CookiesManager.C_KEY_USER);
			password = (String)request.getAttribute(CookiesManager.C_KEY_PASS);
		}
		else {
			userName = loginForm.getUserName();
			password = MD5Encoder.getHash(loginForm.getPassword());
		    rememberMe = loginForm.isRememberMe();
		}
		
		User user = new User();
		user.setEmail(userName);
		user.setPassword(password);

		List<User> resultSet = (new UserHome()).findByExample(user);
		if( resultSet != null &&  resultSet.size() > 0 ) {
			user = resultSet.get(0);
		}

		/*
		 * Find forward path by user role
		 */
		String fwd = findForwardPath( user.getUserRole().getRoleName() );
		
		if (fwd != FAILURE) {
			SessionManager.getInstance().setUser(user, request);
			
			request.getSession().setAttribute(FIRST_NAME, user.getUserName());
			request.getSession().setAttribute(LAST_NAME, user.getUserSurname());
			
			if( user.getLocalization() != null) {
				request.getSession().setAttribute( "org.apache.struts.action.LOCALE", 
									   new Locale( user.getLocalization().getDefaultLocale() ) );
			}
			
			/*
			 * If rememberMe equals true - save data in cookies (password will be saved encrypted by MD5)
			 */
			if(rememberMe) {
				saveUserInfoInCookies(response);
			}
		}
		return mapping.findForward(fwd);
	}
	
	/**
	 * Stores user info in cookies.
	 * @param response
	 */
	private void saveUserInfoInCookies(HttpServletResponse response) {
		response.addCookie(CookiesManager.createCookie(CookiesManager.C_KEY_USER, userName));
		response.addCookie(CookiesManager.createCookie(CookiesManager.C_KEY_PASS, password));
		response.addCookie(CookiesManager.createCookie(CookiesManager.C_KEY_SAVE, "true"));
	}
	
	/**
	 * Defines forward path according to user role
	 * @param userRole
	 * @return forward path
	 */
	private String findForwardPath(String userRole) {
		String fwd = FAILURE;

		if (STUDENT_SUCCESS.equalsIgnoreCase(userRole)) {
			fwd = STUDENT_SUCCESS;
		} else if (INSTRUCTOR_SUCCESS.equalsIgnoreCase(userRole)) {
			fwd = INSTRUCTOR_SUCCESS;
		} else if (ADMIN_SUCCESS.equalsIgnoreCase(userRole)) {
			fwd = ADMIN_SUCCESS;
		}
		return fwd;
	}
}
